package com.aop;

import com.form.CustomModelInfoForm;
import com.mapper.MryeMapper;
import com.util.BeanConvertUtils;
import com.serice.ValueUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * Created by SkinApe on 2021/9/17.
 */
@Component
@Aspect
public class QueryViewAop {

    @Autowired
    MryeMapper mryeMapper;

    @AfterReturning("@annotation(queryViewAndFieldShow)")
    public Object lineToHump(JoinPoint point, QueryViewAndFieldShow queryViewAndFieldShow) throws Throwable {

        Object[] args = point.getArgs();
        //args[0]= BeanConvertUtils.lineToHumpMapList((List<Map<String, Object>>) args[0]);

        return args;
    }

    @Around("@annotation(queryViewAndFieldShow)")
    public Object lineToHump(ProceedingJoinPoint point, QueryViewAndFieldShow queryViewAndFieldShow) throws Throwable {

        Object[] args = point.getArgs();

        if (args != null && args.length > 0) {
            Object obj = args[0];
            System.out.println(obj.getClass());
            if (obj != null && obj.getClass() == HashMap.class) {
                Map<String,Object> data= (Map<String, Object>) obj;
                String sql = ValueUtil.toStr(data.get("sql"));
                //获取视图数据
                Map<String,Object> queryView = (Map<String, Object>) data.get("view");

                //源查询内容
                Map<String,Object> sourceSelectMap=new HashMap<>();
                String[] sourceSelectList=sql.substring(6,sql.indexOf("FROM")).trim().split(",");
                for (String sourceSelect:sourceSelectList){
                    String[] source=sourceSelect.split("AS");
                    String key=source[1].trim().split("\\|")[0];
                    sourceSelectMap.put(key.substring(1),source[1].trim()+";"+source[0].trim());
                }

                String selectSql="";


                //获取视图数据
                //Map<String,Object> queryView= (Map<String, Object>) JSONArray.parse("{\"modelName\":\"生产发料\",\"showFieldAliasList\":\"生产订单号|code;产品编号|productCode;产品名称|productName;供应商|supplierName;时间|time;供应商出款金额|money;生产订单状态|status\",\"screenList\":[{\"field\":\"productCode\",\"vaule\":\"000\",\"type\":\"模糊\"},{\"field\":\"money\",\"vaule\":1,\"type\":\"大于\"},{\"field\":\"money\",\"vaule\":600,\"type\":\"小于\"}],\"sortList\":[{\"field\":\"code\",\"type\":\"Desc\"}],\"groupList\":[{\"field\":\"productCode\"}],\"paging\":{\"page\":0,\"size\":100}}");
                //模块名
                String modelName=ValueUtil.toStr(queryView.get("modelName"));
                //显示字段
                String[] showFieldAliasList=ValueUtil.toStr(queryView.get("showFieldAliasList")).split(";");

                if (showFieldAliasList.length==1&&showFieldAliasList[0].equals("")){
                    Map<String,Object> params=new HashMap<>();
                    String modelSql = "SELECT * FROM a_custom_model_info WHERE model_name=#{code} ORDER BY sort";
                    params.put("code", modelName);
                    params.put("sql", modelSql);
                    List<CustomModelInfoForm> customModelInfoFormList = BeanConvertUtils.sourceListToTargetList(BeanConvertUtils.lineToHumpMapList(mryeMapper.searchList(params)), CustomModelInfoForm.class);
                    showFieldAliasList=new String[customModelInfoFormList.size()];
                    for (int i=0;i<customModelInfoFormList.size();i++){
                        CustomModelInfoForm customModelInfoForm=customModelInfoFormList.get(i);
                        showFieldAliasList[i]=customModelInfoForm.getShowName()+"|"+customModelInfoForm.getTableFieldAlias();

                    }
                }


                    //筛选条件
                    List<Map<String,Object>> screenList= (List<Map<String, Object>>) queryView.get("screenList");
                    //排序
                    List<Map<String,Object>> sortList= (List<Map<String, Object>>) queryView.get("sortList");
                    //分组
                    List<Map<String,Object>> groupList= (List<Map<String, Object>>) queryView.get("groupList");
                    //分页
                    Map<String,Object> paging= (Map<String, Object>) queryView.get("paging");
                    int page=ValueUtil.toInt(paging.get("page"),1);
                    int size=ValueUtil.toInt(paging.get("size"),20);

                    //目标查询内容
                    Map<String,Object> targetSelectMap=new LinkedHashMap<>();
                    //别名对应实际表名
                    Map<String,Object> aliasToField=new LinkedHashMap<>();
                    for (String showField:showFieldAliasList){
                        targetSelectMap.put(showField.split("\\|")[0],showField.split("\\|")[1]);
                    }

                    for (String key:targetSelectMap.keySet()){
                        if (sourceSelectMap.containsKey(key)){
                            String[] source=ValueUtil.toStr(sourceSelectMap.get(key)).split(";");
                            selectSql=selectSql+source[1]+" AS "+source[0]+",";
                            aliasToField.put(ValueUtil.toStr(targetSelectMap.get(key)),source[1]);

                        }
                    }
                    if (!selectSql.equals("")){
                        selectSql=selectSql.substring(0, selectSql.length() - 1);
                        sql="SELECT "+selectSql+" "+sql.substring(sql.indexOf("FROM"));
                        String countSql="SELECT count(1) "+sql.substring(sql.indexOf("FROM"));

                        String whereSql=" WHERE 1=1 ";
                        //添加筛选 排序 分组 分页 业务逻辑
                        for (Map<String,Object> screen:screenList){
                            String type =ValueUtil.toStr(screen.get("type"));
                            String field=ValueUtil.toStr(screen.get("field"));
                            Object vaule=ValueUtil.toStr(screen.get("vaule"));

                            whereSql=whereSql+" AND "+aliasToField.get(screen.get("field"));
                            if (type.equals("模糊")){
                                data.put(field,vaule);
                                //whereSql=whereSql+" like CONCAT('%',#{"+field+"},'%') ";
                                whereSql=whereSql+" like '%'||#{"+field+"}||'%'";
                            }else {
                                if (type.equals("等于")){
                                    whereSql=whereSql+" = ";
                                }else if (type.equals("大于")){
                                    whereSql=whereSql+" > ";
                                }else if (type.equals("小于")){
                                    whereSql=whereSql+" < ";
                                }
                                if (data.containsKey(field)){
                                    data.put(field+"Two",vaule);
                                    whereSql=whereSql+"#{"+field+"Two}";
                                }else {
                                    data.put(field,vaule);
                                    whereSql=whereSql+"#{"+field+"}";
                                }
                            }


                        }
                        //总条数
                        countSql=countSql+whereSql;
                        data.put("sql", countSql);
                        Map<String, Object> mapList = mryeMapper.search(data);
                        //总条数
                        data.put("count", mapList.get("count"));
                        for (Map<String,Object> sort:sortList){
                            String type = ValueUtil.toStr(sort.get("type"));
                            String field = ValueUtil.toStr(aliasToField.get(sort.get("field")));
                            whereSql=whereSql+" ORDER BY "+field+" "+type;
                        }
                        data.put("groupList",groupList);

                        whereSql=whereSql+" LIMIT #{size} offset #{page}*#{size}";
                        data.put("size",size);
                        data.put("page",page);

                        sql=sql+whereSql;

                        data.put("sql",sql);
                        args[0]=data;
                    }


                }

        }
        Object returnValue = point.proceed(args);
        return returnValue;
    }
}
